﻿using System;
using System.Collections.Generic;
using Mono.Data.Sqlite;
using Model;

namespace MDFGame
{
    //数据库组件
    public class SqlManager
    {

        private bool IsConnection;
        private string dbPath;
        private string sqlCommand;
        private SqliteConnection dbConnection;
        private SqliteCommand dbCommand;//数据库指令格式
        private SqliteDataReader dataReader;//结果集

        private Dictionary<int, TEffect> Teffects = new Dictionary<int, TEffect>();//全局特性表
        private List<Series> SList = new List<Series>();//全局系列表
        private Dictionary<int, CardInfo> CardList = new Dictionary<int, CardInfo>();//全局卡片表

        public SqlManager(string path)
        {
            IsConnection = false;
            dbPath = path;
            dbInit();
        }
        public void SqlReConnect(string path)
        {
            if (IsConnection)
            {
                return;
            }
            dbPath = path;
            dbInit();
        }
        private void dbInit()
        {
            try
            {
                dbConnection = new SqliteConnection(@"Data Source=" + dbPath);
                dbConnection.Open();
                Log.Info("数据库连接成功");
                IsConnection = true;
                Teffects.Clear();
                SList.Clear();
                CardList.Clear();

                InitData();
            }
            catch (Exception e)
            {
                IsConnection = false;
                Log.Error(e);
            }
        }
        /// <summary>
        /// 更新数据库路径重新连接
        /// </summary>
        /// <param name="path">指定路径</param>
       
        private void InitData()
        {
            if (!IsConnection)
            {
                return;
            }
            LoadTList();
            LoadSList();
            LoadAllCards();
        }
        /// <summary>
        /// 读取存在的特性表
        /// </summary>
        private void LoadTList()
        {
            sqlCommand = "select * from TList";
            ExecuteQuery();
            int t = 0;
            while (dataReader.Read())
            {
                Teffects.Add(t,new TEffect(
                    dataReader["TName"].ToString(),
                    dataReader["TText"].ToString()
                    ));
                t++;
            }
        }
        /// <summary>
        /// 读取全局系列表【编辑器用+缩小索引范围】
        /// </summary>
        private void LoadSList()
        {
            sqlCommand = "select * from Series";
            ExecuteQuery();
            while (dataReader.Read())
            {
                SList.Add(new Series(
                    dataReader["Call"].ToString(),
                    dataReader["Name"].ToString()
                    ));
            }
        }
        /// <summary>
        /// 读取所有数据库卡片
        /// </summary>
        private void LoadAllCards()
        {
            if (!IsConnection)
            {
                return;
            }
            int count = 1;//用于卡片字典值叠加
            SqliteDataReader tempdata;
            SqliteDataReader tempdata1;
            foreach(Series series in SList)
            {
                sqlCommand = $"select b.* from Basic b where b.Series = (select id from Series where Call='{series.SCall}')";
                ExecuteQuery();
                //获取的卡片组的基本信息
                tempdata = dataReader;
                //依次遍历各个卡片数据
                while (tempdata.Read())
                {
                    //根据当前卡片类型参数去查询具体卡数据内容
                    switch ((CardType)tempdata["CardType"])
                    {
                        
                        case CardType.Character:
                            {
                                //根据卡ID获取当前角色的技能组
                                sqlCommand = $"select * from Skill where ID={tempdata["ID"]}";
                                ExecuteQuery();
                                List<Skill> tskills = new List<Skill>();
                                while (dataReader.Read())
                                {
                                    tskills.Add(new Skill(
                                        (SkillType)dataReader["SkillType"],
                                        dataReader["SkillText"].ToString())
                                        );
                                }
                                Skill[] skills = tskills.ToArray();
                                //根据卡ID获取当前角色的角色信息
                                sqlCommand = $"select * from Character where ID={tempdata["ID"]}";
                                ExecuteQuery();
                                //装载角色卡数据
                                CardList.Add(count, new CharacterInfo(
                                    series.SCall,//系列
                                    (int)tempdata["Num"],//系列中的编号
                                    tempdata["Rare"].ToString(),//稀有度
                                    tempdata["Name"].ToString(),//名称
                                    bool.Parse(tempdata["IsfinalCard"].ToString().ToLower()),//终符标记
                                    (CardType)tempdata["CardType"],//卡片类型
                                    tempdata["Illust"].ToString(),//绘师信息
                                    dataReader["Title"].ToString(),//角色称号信息
                                    dataReader["Describe"].ToString(),//角色介绍信息
                                    skills//技能组
                                ));
                                //当前系列的卡片索引中加入这张卡的字典key
                                series.SCard.Add(count);
                                count++;
                            }
                            break;
                        case CardType.Battle:
                            {
                                //获取当前卡片的特性映射表
                                sqlCommand = $"select * from [Connect_B&T] where BID={tempdata["ID"]}";
                                ExecuteQuery();
                                tempdata1 = dataReader;
                                //根据映射表中的映射的特性ID读取对应的特性
                                while (tempdata1.Read())
                                {
                                    //根据映射表中的映射的特性ID读取对应的特性
                                    sqlCommand = $"select * from TList where ID={tempdata1["TID"]}";
                                    ExecuteQuery();
                                    //该卡片对应特性表
                                    List<int> tt = new List<int>();
                                    while (dataReader.Read())
                                    {
                                       foreach(int te in Teffects.Keys)
                                        {
                                            //将对应的特性关联到该卡片特性组中
                                            if (Teffects[te].TName.Equals(dataReader["TName"]))
                                            {
                                                tt.Add(te);
                                                return;
                                            }

                                        }
                                    }
                                    //获取对应卡片的战斗卡部分信息
                                    sqlCommand = $"select * from Battle where ID={tempdata["ID"]}";
                                    ExecuteQuery();
                                    CardList.Add(count, new BattleInfo(
                                        series.SCall,//系列
                                        (int)tempdata["Num"],//系列中的编号
                                        tempdata["Rare"].ToString(),//稀有度
                                        tempdata["Name"].ToString(),//名称
                                        bool.Parse(tempdata["IsfinalCard"].ToString().ToLower()),//终符标记
                                        (CardType)tempdata["CardType"],//卡片类型
                                        tempdata["Illust"].ToString(),//绘师信息
                                        (int)dataReader["Level"],//华丽度
                                        (int)dataReader["Cost"],//代价
                                        (int)dataReader["BattleNum"],//战斗力数值
                                        (BattleType)dataReader["BattleType"],//战斗类型
                                        dataReader["EffectText"].ToString(),//效果描述
                                        dataReader["ConditionText"].ToString(),//效果条件
                                        tt//对应特性表
                                        ));
                                    //当前系列的卡片索引中加入这张卡的字典key
                                    series.SCard.Add(count);
                                    count++;
                                }
                            }
                            break;
                        case CardType.Special:
                            {
                                //根据卡ID获取特殊卡信息
                                sqlCommand = $"select * from Special where ID={tempdata["ID"]}";
                                ExecuteQuery();
                                CardList.Add(count, new SpecialInfo(
                                    series.SCall,//系列
                                    (int)tempdata["Num"],//系列中的编号
                                    tempdata["Rare"].ToString(),//稀有度
                                    tempdata["Name"].ToString(),//名称
                                    bool.Parse(tempdata["IsfinalCard"].ToString().ToLower()),//终符标记
                                    (CardType)tempdata["CardType"],//卡片类型
                                    tempdata["Illust"].ToString(),//绘师信息
                                    (int)dataReader["Level"],//华丽度
                                    (int)dataReader["Cost"],//代价
                                    dataReader["EffectText"].ToString(),//效果描述
                                    dataReader["ConditionText"].ToString(),//效果条件
                                    (SpecialType)dataReader["CardType"]
                                    ));
                                //当前系列的卡片索引中加入这张卡的字典key
                                series.SCard.Add(count);
                                count++;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }     
        }
        /// <summary>
        /// 获取单张卡片数据库中ID
        /// </summary>
        /// <param name="name">卡片名称缩写[RM-1]</param>
        /// <returns></returns>
        public int GetCardID(string name)
        {
            string[] Cname = name.Split('-');
            CardType cardType;
            if (Cname.Length < 2)
            {
                Log.Error("卡片名称非法！");
                return -1;
            }
            cardType = ((Cname.Length > 2) ? CardType.Character : CardType.Undefined);
            //找这张卡，找到了直接返回卡片引用
            foreach (Series s in SList)
            {
                if (s.SCall.Equals(Cname[0]))
                {
                    int tnum = int.Parse(Cname[Cname.Length - 1]);
                    //注意系列表里面不同系列下的SCard保存的int不是卡片num而是CardList的key
                    if (cardType == CardType.Character)
                    {
                        foreach (int key in s.SCard)
                        {
                            if (CardList[key].Snum == tnum && CardList[key].CType == cardType)
                            {
                                return key;
                            }
                        }
                    }
                    else
                    {
                        foreach (int key in s.SCard)
                        {
                            if (CardList[key].Snum == tnum && CardList[key].CType != CardType.Character)
                            {
                                return key;
                            }
                        }
                    }
                }
            }
            return -1;
        }
        /// <summary>
        /// 获取单张卡片
        /// </summary>
        /// <param name="name">卡片名称缩写[RM-1]</param>
        /// <returns></returns>
        public CardInfo GetCardByName(string name)
        {
            string[] Cname = name.Split('-');
            CardType cardType;
            if (Cname.Length < 2)
            {
                Log.Error("卡片名称非法！");
                return null;
            }
            cardType = ((Cname.Length > 2) ? CardType.Character : CardType.Undefined);
            //找这张卡，找到了直接返回卡片引用
            foreach (Series s in SList)
            {
                if (s.SCall.Equals(Cname[0]))
                {
                    int tnum = int.Parse(Cname[Cname.Length - 1]);
                    //注意系列表里面不同系列下的SCard保存的int不是卡片num而是CardList的key
                    if (cardType == CardType.Character)
                    {
                        foreach (int key in s.SCard)
                        {
                            if (CardList[key].Snum == tnum && CardList[key].CType == cardType)
                            {
                                return CardList[key];
                            }
                        }
                    }
                    else
                    {
                        foreach (int key in s.SCard)
                        {
                            if (CardList[key].Snum == tnum && CardList[key].CType != CardType.Character)
                            {
                                return CardList[key];
                            }
                        }
                    }            
                }
            }
            return null;
        }
        /// <summary>
        /// 获取单张卡片
        /// </summary>
        /// <param name="key">卡片字典中的ID</param>
        /// <returns></returns>
        public CardInfo GetCardByID(int key)
        {
            return CardList[key];
        }
        /// <summary>
        /// 获取对应系列的所有卡片
        /// </summary>
        /// <param name="call">系列英文缩写[RM]</param>
        /// <returns></returns>
        public List<CardInfo> GetCardsBySeries(string call)
        {
            foreach(Series s in SList)
            {
                if (s.SCall.Equals(call))
                {
                    List<CardInfo> temp = new List<CardInfo>();
                    foreach(int key in s.SCard)
                    {
                        temp.Add(CardList[key]);
                    }
                    return temp;
                }
            }
            return null;
        }
        public Series GetSeries(string call)
        {
            foreach(Series s in SList)
            {
                if (s.SCall.Equals(call))
                    return s;
            }
            return (new Series("call","unknown"));
        }
        public TEffect GetTEffect(int i)
        {
            return Teffects[i];
        }
        /// <summary>
        /// 执行SQL命令
        /// </summary>
        /// <returns>The query.</returns>
        /// <param name="queryString">SQL命令字符串</param>
        private void ExecuteQuery()
        {
            dbCommand = dbConnection.CreateCommand();
            dbCommand.CommandText = sqlCommand;
            dataReader = dbCommand.ExecuteReader();
        }
        /// <summary>
        /// 关闭数据库连接
        /// </summary>
        private void CloseConnection()
        {
            //销毁Command
            if (dbCommand != null)
            {
                dbCommand.Cancel();
            }
            dbCommand = null;

            //销毁Reader
            if (dataReader != null)
            {
                dataReader.Close();
            }
            dataReader = null;

            //销毁Connection
            if (dbConnection != null)
            {
                dbConnection.Close();
            }
            dbConnection = null;
            Dispose();
        }

        public void Dispose()
        {
            CloseConnection();
        }
    }
}
